package com.mask.im.business.service.impl;

import com.mask.im.business.model.dto.UserDetailsDTO;
import com.mask.im.business.service.RedisService;
import com.mask.im.business.service.TokenService;
import com.mask.im.business.common.constant.CommonConstant;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Base64;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;

import static com.mask.im.business.common.constant.RedisConstant.USER_LOGIN;

@Service
public class TokenServiceImpl implements TokenService {

	@Autowired
	private RedisService redisService;

	private static final String KEY = "example-jwt-secret-key-2024"; //自定义加密秘钥

	private static final String AES = "AES";    //加密类型

	private static final String AUTHORITY = "Authorization"; //固定头部获取的token的key值

	/**
	 * 创建token复合操作
	 * @param userDetailsDTO
	 * @return
	 */
	@Override
	public String createToken(UserDetailsDTO userDetailsDTO) {
		//刷新用户信息
		refresh(userDetailsDTO);
		String userId = userDetailsDTO.getId().toString();
		return createToken(userId);
	}

	/**
	 * 创建token
	 * @param subject
	 * @return
	 */
	@Override
	public String createToken(String subject) {
		SignatureAlgorithm algorithm = SignatureAlgorithm.HS256;
		SecretKey secretKey = getSecretKey();
		return Jwts.builder()
				.setId(Uuid())
				.setSubject(subject)
				.setIssuer(KEY)
				.signWith(algorithm,secretKey).compact();
	}

	/**
	 * 刷新用户信息
	 * @param userDetailsDTO
	 */
	@Override
	public void refresh(UserDetailsDTO userDetailsDTO) {
		LocalDateTime dateTime = LocalDateTime.now();

//		userDetailsDTO.setExpireTime(dateTime.plusSeconds(CommonConstant.EXPIRE_TIME));
		String userId = userDetailsDTO.getId().toString();
		redisService.hSet(USER_LOGIN,userId,userDetailsDTO,60*60*24);

	}

	/**
	 * 是否刷新用户信息
	 * @param userDetailsDTO
	 */
	@Override
	public void renewToken(UserDetailsDTO userDetailsDTO) {

		//获取当前时间
		LocalDateTime nowTime = LocalDateTime.now();
		//获取用户redis信息过期时间
		Date expireTime = userDetailsDTO.getExpireTime();
		//比较如果用户redis信息过期时间小于当前时间30秒则进行刷新
//		if (Duration.between(nowTime,expireTime).toMillis()<30*1000){
//			refresh(userDetailsDTO);
//		}
	}

	/**
	 * 将token进行解密
	 * @param token
	 * @return
	 */
	@Override
	public Claims parseToken(String token) {
		//获取加密方法进行解密操作
		SecretKey secretKey = getSecretKey();
		return Jwts.parser().setSigningKey(secretKey).parseClaimsJws(token).getBody();
	}

	/**
	 * 获取登入用户的信息
	 * @param request
	 * @return
	 */
	@Override
	public UserDetailsDTO getUserDetailsDTO(HttpServletRequest request) {
		String token = request.getHeader(AUTHORITY);
		if(Objects.isNull(token)){
			return null;
		}
		Claims claims = parseToken(token);
		String userId = claims.getSubject();
		return (UserDetailsDTO)redisService.hGet(USER_LOGIN, userId);
	}

	@Override
	public void delLoginUser(Integer userId) {
		redisService.hDel(USER_LOGIN, String.valueOf(userId));
	}

	/**
	 * 随机字符串
	 * @return
	 */
	private String Uuid(){
		return UUID.randomUUID().toString().replaceAll("-","");
	}

	/**
	 * 加密方式
	 * @return
	 */
	private SecretKey getSecretKey(){
		byte[] encodeKey = Base64.getDecoder().decode(KEY);
		return new SecretKeySpec(encodeKey,0,encodeKey.length,AES);
	}
}
